home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / doom / ldhe-src.0 / ldhe-src / dehacked / source / playview.cc < prev    next >
C/C++ Source or Header  |  1995-04-20  |  9KB  |  396 lines

  1. // DeHackEd version 2.3
  2. // Written by Greg Lewis, gregl@umich.edu
  3. // If you release any versions of this code, please include
  4. // the author in the credits.  Give credit where credit is due!
  5.  
  6. #include <stdio.h>
  7. #include <ctype.h>
  8. #include <fcntl.h>
  9. #include <errno.h>
  10. #include <string.h>
  11.  
  12. #include "dehacked.h"
  13. #include "playview.h"
  14.  
  15. #undef TEXT                // Defined in dehacked.h
  16. #undef WIDTH                // Defined in dehacked.h
  17. #undef HEIGHT                // Defined in dehacked.h
  18. #include "ttyobj.h"
  19.  
  20. // Plays the actual sound (maybe)
  21. int Play(ResourceS entry)
  22. {
  23.     struct snd_header header;
  24.     int audio_fd;
  25.     unsigned char *chunk;
  26.     int i, samplei;
  27.     unsigned char ulaw;
  28.     float sum = 0, increment;
  29.  
  30.     fseek(doomwadfp, entry.resstart, SEEK_SET);
  31.     fread((void *)&header, sizeof(header), 1, doomwadfp);
  32.     if ( NEED_SEX ) {
  33.         bytesec(header.magic);
  34.         bytesec(header.sample_rate);
  35.         bytesec(header.num_samples);
  36.     }
  37.  
  38.     if ( header.magic != SND_MAGIC ) {
  39.         Printwindow("Not a sound resource!", ERROR);
  40.         return(-1);
  41.     }
  42.     chunk = new unsigned char[header.num_samples];
  43.     if ( chunk == NULL ) {
  44.         Printwindow("Not enough memory!", ERROR);
  45.         return(-1);
  46.     }
  47.  
  48.     if ((audio_fd=open(_PATH_DEVAUDIO, O_WRONLY, 0)) <0)
  49.     {
  50.         if ( errno == EBUSY )
  51.             Printwindow("Sound card in use!", ERROR);
  52.         else
  53.             Printwindow("Sound card not found!", ERROR);
  54.         return -1;
  55.     }
  56.     fread((void *)chunk, 1, header.num_samples, doomwadfp);
  57.  
  58.     /* increment is the number of bytes to read each time */
  59.     increment = ((float)header.sample_rate)/8000;
  60.  
  61.  
  62.     /* Write to the sound card */
  63.     for ( i=0; i<header.num_samples; ) {
  64.         /* convert the excess 128 to two's complement */
  65.         samplei = 0x80 - chunk[i];
  66.         /* increase the volume, convert to uLAW */
  67.         ulaw = (unsigned char)sample_cvt(samplei * 16);
  68.         /* Output the converted sample */
  69.         write(audio_fd, (char *)&ulaw, 1);
  70.  
  71.         /* skip input to compensate for sampling frequency diff */
  72.         sum += increment;
  73.         while(sum > 0) {
  74.             ++i; --sum;
  75.         }
  76.     }
  77.     close(audio_fd);
  78.     return 0;
  79. }
  80.  
  81. // Plays a sound.
  82.  
  83. int Playsound(long soundnum)
  84. {
  85.     ResourceS entry = {0, 0, ""};
  86.     char nametemp[7];
  87.     char soundname[9] = "DS";
  88.  
  89.     Getsoundname((int)soundnum, nametemp);
  90.  
  91.     if (strcmp(nametemp, "none") == 0)
  92.         return -1;
  93.     else if (strcmp(nametemp, "ERROR") == 0)
  94.     {
  95.         Printwindow("Not a valid sound number!", ERROR);
  96.         return -1;
  97.     }
  98.  
  99.     strcat(soundname, strupr(nametemp));
  100.  
  101.     // Find the correct sound
  102.     if (Searchforentry(soundname, &entry) == 0)
  103.     {
  104.         Printwindow("Could not find sound in the DOOM.WAD file!", ERROR);
  105.         return -1;
  106.     }
  107.  
  108.     Play(entry);
  109.  
  110.     return 0;
  111. }
  112.  
  113.  
  114. // Actually draw a frame on the screen
  115. int Drawframe(ResourceS entry, EBool flip)
  116. {
  117.     int width=0, height=0, xoff=0, yoff=0;
  118.     struct frame_header header;
  119.     unsigned long *picoff;
  120.     int i, j;
  121.     unsigned char numpixels;
  122.     unsigned char *pixinfo;
  123.     int curoff = 0, curx, cury;
  124.     int step;
  125.  
  126.     // Get the initial info
  127.     fseek(doomwadfp, entry.resstart, SEEK_SET);
  128.     fread(&header, 1, sizeof(header), doomwadfp);
  129.     if ( NEED_SEX ) {
  130.         bytesec(header.width);
  131.         bytesec(header.height);
  132.         bytesec(header.l_offset);
  133.         bytesec(header.t_offset);
  134.     }
  135.     width=header.width;
  136.     height=header.height;
  137.     xoff=header.l_offset;
  138.     yoff=header.t_offset;
  139.  
  140.     // Set the x and y offsets if we're dealing with a weapon picture,
  141.     // which has a negative offset.
  142.     if (xoff < 0)
  143.         xoff = width/2;
  144.     if (yoff < 0)
  145.         yoff = 80;
  146.  
  147.     yoff = 100 - yoff/2;
  148.  
  149.     // If we have to flip the image along the y axis, set the x variable
  150.     // to go left instead of right, and start it on the right side of the
  151.     // image.
  152.     if (flip)
  153.     {
  154.         step = -1;
  155.         curx = 160 + xoff;
  156.     }
  157.     else
  158.     {
  159.         step = 1;
  160.         curx = 160 - xoff;
  161.     }
  162.  
  163.     // Get memory for image
  164.     picoff = new unsigned long[width];
  165.     pixinfo = new unsigned char[entry.reslength];
  166.  
  167.     if (picoff == NULL || pixinfo == NULL)
  168.         return -1;
  169.  
  170.     // Get the column info
  171.     fread(picoff, width, 4, doomwadfp);
  172.     if ( NEED_SEX ) {
  173.         for ( int sexi=0; sexi<width; ++sexi )
  174.             picoff[sexi] = bytesex(picoff[sexi]);
  175.     }
  176.  
  177.     // Read in the rest of the image stuff
  178.     fseek(doomwadfp, entry.resstart+picoff[0], SEEK_SET);
  179.     fread(pixinfo, (unsigned int)(entry.reslength-picoff[0]), 1, doomwadfp);
  180.  
  181.     // Loop through each column
  182.     for (i=0; i<width; i++, curx += step)
  183.     {
  184.         curoff = (int)(picoff[i]-picoff[0]);
  185.  
  186.         while (i != width-1 && (curoff != picoff[i+1]-picoff[0]-1))
  187.         {
  188.             cury = yoff + pixinfo[curoff];
  189.             numpixels = pixinfo[curoff+1];
  190.             curoff += 3;
  191.             for (j=0; j<numpixels; j++, cury++) {
  192.                 if (curx <= 319 && cury <= 199) {
  193.                     drawpoint(curx, cury,
  194.                             pixinfo[curoff++]);
  195.                 }
  196.             }
  197.             curoff++;
  198.         }
  199.     }
  200.  
  201.     // Free memory
  202.     delete[] picoff;
  203.     delete[] pixinfo;
  204.     return 0;
  205. }
  206.  
  207.  
  208. // General driving forces behind showing a frame.
  209. int Showframe(long framenum)
  210. {
  211.     int curview = 1;
  212.     ResourceS entry = {0, 0, ""};
  213.     EBool ExitLoop = NO;
  214.     EBool flip, draw = YES;
  215.     char framename[9];
  216.     char input;
  217.     struct color colormap[256];
  218.  
  219. #ifdef HAVE_MOUSE
  220.     unsigned int x, y;        // Mouse x and y
  221.     EButton lbutton, rbutton;// State of left and right buttons
  222. #endif
  223.     char order[9] = {0, 5, 8, 7, 6, 1, 4, 3, 2};
  224.  
  225.     if ( ! has_graphics() ) {
  226.         Printwindow(
  227.             "Not running in a graphics capable display!", ERROR);
  228.         return -1;
  229.     }
  230.     
  231.     Getframename((int)framenum, framename);
  232.  
  233.     if (strcmp(framename, "none") == 0)
  234.         return -1;
  235.     else if (strcmp(framename, "ERROR") == 0) {
  236.         Printwindow("Not a valid frame number!", ERROR);
  237.         return -1;
  238.     }
  239.  
  240.  
  241.     // Find the Doom palette
  242.     if (Searchforentry("PLAYPAL", &entry) == 0)
  243.     {
  244.         Printwindow("Could not find the default palette!", ERROR);
  245.         return -1;
  246.     }
  247.  
  248.     // Get the palette setup correctly.
  249.     fseek(doomwadfp, entry.resstart, SEEK_SET);
  250.     fread(&colormap, sizeof(struct color), 256, doomwadfp);
  251.  
  252.     // Search for the generic frame ending in '0' first
  253.     framename[5] = '0';
  254.     framename[6] = 0;
  255.     if (Searchforentry(framename, &entry) == 0)
  256.     {
  257.         framename[5] = '1';
  258.         if (Searchforentry(framename, &entry) == 0)
  259.         {
  260.             framename[5] = '5';
  261.             if (Searchforentry(framename, &entry) == 0)
  262.             {
  263.                 Printwindow("Could not find frame in the Doom WAD file!", ERROR);
  264.                 return -1;
  265.             }
  266.         }
  267.     }
  268.  
  269.     // Init graphics, my crude way
  270.     toMCGA();
  271.     set_colormap(colormap);
  272.  
  273.     // While they haven't exited the frame viewer...
  274.     while (ExitLoop == NO)
  275.     {
  276.         // Don't flip the image by default
  277.         flip = NO;
  278.  
  279.         // Get the frame name of the current frame to draw and find that
  280.         // entry in the WAD file.
  281.         // If the sixth character is '0', we'll ASSUME it's been read into
  282.         // entry already, and is ready to display.
  283.         if (framename[5] != '0')
  284.         {
  285.             framename[5] = '0' + curview;
  286.             if (Searchforentry(framename, &entry) == 0)
  287.             {
  288.                 framename[5] = '0' + order[curview];
  289.                 if (Searchforentry(framename, &entry) == 0)
  290.                 {
  291.                     ExitLoop = YES;
  292.                     break;
  293.                 }
  294.                 else
  295.                     flip = YES;
  296.             }
  297.         }
  298.  
  299.         // Only redraw if we have to.
  300.         if (draw == YES)
  301.         {
  302.             clsMCGA();
  303.             MCGAPutsXY(0, 0, "Escape: quit", 92);
  304.             MCGAPutsXY(0, 1, "Space: Next Frame", 92);
  305.  
  306.             if (entry.resname[5] != '0')
  307.                 MCGAPutsXY(0, 2, "Left/right: rotate", 92);
  308.  
  309.             // If drawing the last frame failed for some reason, quit
  310.             if (Drawframe(entry, flip) == -1)
  311.             {
  312.                 ExitLoop = YES;
  313.                 break;
  314.             }
  315.             flush();
  316.             draw = NO;
  317.         }
  318.  
  319.         if (Waitforevent(NO))
  320.         {
  321.             input = getch();
  322.  
  323.             // If the first input character is 0, it's an extended key
  324.             // (function or arrow, basically).  We only care about arrow
  325.             // keys if the picture can be rotated, so check that too.
  326.             if (!input)
  327.             {
  328.                 input = getch();
  329.                 if (input == RIGHT && (entry.resname[5] != '0'))
  330.                 {
  331.                     if (curview > 1)
  332.                         curview--;
  333.                     else
  334.                         curview = 8;
  335.                     draw = YES;
  336.                 }
  337.                 else if (input == LEFT && (entry.resname[5] != '0'))
  338.                 {
  339.                     if (curview < 8)
  340.                         curview++;
  341.                     else
  342.                         curview = 1;
  343.                     draw = YES;
  344.                 }
  345.                 input = 0;
  346.             }
  347.         }
  348. #ifdef HAVE_MOUSE
  349.         else
  350.         {
  351.             input = 0;
  352.             getLastEvent(&x, &y, &lbutton, &rbutton);
  353.  
  354.             if (rbutton == buttonUp && LastEventButtons & RIGHTBUTTON)
  355.                 input = ESC;
  356.             if (lbutton == buttonUp && LastEventButtons & LEFTBUTTON)
  357.                 input = ' ';
  358.         }
  359. #endif
  360.  
  361.         switch (tolower(input))
  362.         {
  363.             case ESC:
  364.                 ExitLoop = YES;
  365.                 break;
  366.             case ' ':
  367.                 if (framedata[framenum][NEXTFRAME] == 0)
  368.                     ExitLoop = YES;
  369.                 else
  370.                 {
  371.                     framenum = framedata[framenum][NEXTFRAME];
  372.                     Getframename((int)framenum, framename);
  373.                     if (strcmp(framename, "none") == 0 ||
  374.                          strcmp(framename, "ERROR") == 0)
  375.                     {
  376.                         ExitLoop = YES;
  377.                         break;
  378.                     }
  379.  
  380.                     // Search for the generic frame ending in '0' first
  381.                     framename[5] = '0';
  382.                     framename[6] = 0;
  383.                     if (Searchforentry(framename, &entry) == 0)
  384.                         framename[5] = '1';
  385.                     draw = YES;
  386.                 }
  387.                 break;
  388.         }
  389.     }
  390.  
  391.     // Reinit text, my very crude way
  392.     totext();
  393.     _setcursortype(_NOCURSOR);
  394.     return 0;
  395. }
  396.